import os
import sys
import time
import webbrowser
import winsound
import pyperclip

from PySide6.QtWidgets import QMenu
from PySide6 import QtCore
from PySide6.QtGui import QStandardItemModel, QStandardItem, QAction
from PySide6.QtGui import QPixmap, QPainter
from PySide6.QtWidgets import QApplication, QMainWindow, QMessageBox, QHeaderView, QTableView
from PySide6.QtCore import QTimer, Qt, QSize,QThread, Signal,QModelIndex, QEvent
from mydesign_ui import Ui_MainWindow  # 导入生成的 Python UI 类

from db import get_data_from_db, mark_as_old, delete_item

import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("app.log"),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)


class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.scene = None
        self.ui = Ui_MainWindow()  # 创建 UI 实例
        self.ui.setupUi(self)  # 将 UI 应用到 QMainWindow

        # 连接表格的点击信号
        self.ui.tableView.clicked.connect(self.on_row_click)
        self.ui.tableView.doubleClicked.connect(self.on_row_double_click)  # 连接双击信号
        self.ui.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.tableView.customContextMenuRequested.connect(self.show_context_menu)
        self.ui.saveButton.clicked.connect(self.save_cache)

        # 连接关键词和过滤词编辑框的文本变化信号
        self.ui.keywordsEdit.textChanged.connect(self.on_text_changed)
        self.ui.filterEdit.textChanged.connect(self.on_text_changed)

        # 创建标准项模型
        self.model = QStandardItemModel()
        # 设置表头
        self.model.setHorizontalHeaderLabels(["标题", "价格", "提示", "抓取时间","链接","图片链接"])
        # 设置模型到 QTableView
        self.ui.tableView.setModel(self.model)

        # 在窗口显示后设置表格列宽
        QtCore.QTimer.singleShot(0, self.setup_table_view)  # 延迟调用

        self.display_data()
        # 加载关键字缓存
        self.load_cache()

        # 定时器：每 10 秒刷新一次数据
        self.refresh_timer = QTimer(self)
        self.refresh_timer.timeout.connect(self.display_data)  # 定时调用 display_data
        self.refresh_timer.start(10000)  # 10 秒

    def load_cache(self):
        def load_or_create_file(file_path):
            if not os.path.exists(file_path):
                logger.warning(f"未找到缓存的文件 {file_path}，正在创建一个新文件。")
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write("")  # 创建一个空文件
            with open(file_path, 'r', encoding='utf-8') as f:
                return f.readlines()

        # 加载关键字和过滤词
        keywords = load_or_create_file('keywords.txt')
        filter_words = load_or_create_file('filter_words.txt')

        # 设置到对应的输入框
        self.ui.keywordsEdit.setPlainText(''.join(keywords))
        self.ui.filterEdit.setPlainText(''.join(filter_words))

    def load_cached_keywords(self):
        # 从文件或其他地方加载关键字和过滤列表
        try:
            with open('keywords.txt', 'r', encoding='utf-8') as f:
                keywords = f.readlines()
                self.ui.keywordsEdit.setPlainText(''.join(keywords))
        except FileNotFoundError:
            logger.warning("未找到缓存的关键字文件。")
            pass

    def save_cache(self):
        """窗口关闭事件，保存关键字和过滤词"""
        keywords = self.ui.keywordsEdit.toPlainText()
        filter_words = self.ui.filterEdit.toPlainText()

        with open('keywords.txt', 'w', encoding='utf-8') as f:
            f.write(keywords)  # 保存关键字

        with open('filter_words.txt', 'w', encoding='utf-8') as f:
            f.write(filter_words)  # 保存过滤词

        print("保存关键字和过滤关键字")

    def on_text_changed(self):
        """当关键字或过滤词框内容发生变化时，更新开始按钮状态"""
        # 获取当前关键字和过滤词内容
        keywords_text = self.ui.keywordsEdit.toPlainText()
        filter_text = self.ui.filterEdit.toPlainText()

        # 判断内容是否变化
        if keywords_text.strip() or filter_text.strip():
            self.ui.saveButton.setDisabled(False)  # 启用开始按钮
        else:
            self.ui.saveButton.setDisabled(True)  # 禁用开始按钮
        print("on_text_changed")

    def setup_table_view(self):
        # 设置选择行为为选择整行
        self.ui.tableView.setSelectionBehavior(QTableView.SelectRows)
        # 设置固定列宽度
        self.ui.tableView.setColumnWidth(0, 350)
        self.ui.tableView.setColumnWidth(1, 100)
        self.ui.tableView.setColumnWidth(2, 150)
        self.ui.tableView.setColumnWidth(3, 150)
        self.ui.tableView.setColumnWidth(4, 150)
        self.ui.tableView.setColumnWidth(5, 150)

        # 设置标题居中对齐
        header = self.ui.tableView.horizontalHeader()
        header.setSectionsMovable(True)  # 允许移动列
        header.setStretchLastSection(True)  # 让最后一列伸展以填满剩余空间

        for i in range(self.model.columnCount()):
            # header.setSectionResizeMode(i, QHeaderView.Fixed)  # 固定宽度
            header.setStyleSheet("QHeaderView::section { text-align: center; }")  # 设置居中

    def setup_context_menu(self):
        self.ui.tableView.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.ui.tableView.customContextMenuRequested.connect(self.show_context_menu)

    def show_context_menu(self, pos):
        # 获取当前鼠标位置的索引
        index = self.ui.tableView.indexAt(pos)

        if index.isValid():
            # 获取所有被选择的行索引
            selected_rows = list(set(index.row() for index in self.ui.tableView.selectedIndexes()))  # 只获取唯一的行索引

            menu = QMenu(self.ui.tableView)

            # 创建“复制”菜单项
            copy_link_action = QAction("复制商品链接", self)
            copy_link_action.triggered.connect(lambda: self.copy_item_link(selected_rows))
            menu.addAction(copy_link_action)

            # 创建“标为已读”菜单项
            mark_as_read_action = QAction("标为已读", self)
            mark_as_read_action.triggered.connect(lambda: self.mark_as_read(selected_rows))
            menu.addAction(mark_as_read_action)

            # 创建“删除”菜单项
            delete_action = QAction("删除", self)
            delete_action.triggered.connect(lambda: self.delete_item(selected_rows))
            menu.addAction(delete_action)

            # 显示右键菜单
            menu.exec(self.ui.tableView.viewport().mapToGlobal(pos))

    def copy_item_link(self, rows):
        urls = [self.model.item(row, 4).text() for row in rows]
        urls_text = "\n".join(urls)

        # 将字符串复制到剪切板
        pyperclip.copy(urls_text)

        # print("URLs copied to clipboard:")
        # print(urls_text)  # 可选：在控制台打印复制的 URLs

    def mark_as_read(self, rows):
        urls = [self.model.item(row, 4).text() for row in rows]  # 只处理唯一的行
        print(f"mark_as_read:{urls}")
        mark_as_old(urls)
        for row in rows:
            # 更新颜色
            self.update_row_color(row)
        # self.display_data()  # 更新表格展示

    def delete_item(self, rows):
        urls = [self.model.item(row, 4).text() for row in rows]
        print(f"delete_item:{urls}")
        delete_item(urls)
        # 从表格中删除对应的行
        for row in sorted(rows, reverse=True):  # 从高索引到低索引删除，避免索引错位
            self.model.removeRow(row)

        # self.display_data()  # 更新表格展示


    def on_row_click(self, index: QModelIndex):
        if index.isValid():  # 确保点击的是有效的索引
            row = index.row()  # 获取点击行的索引
            image_path = self.model.item(row, 5).text()

            self.load_image(image_path)  # 加载图片并显示
            self.mark_as_read([row])  # 单击标注已读

            # # 选中当前行
            # self.ui.tableView.selectRow(row)
            #
            # # 确保当前行在滚动条可见范围内
            # self.ui.tableView.scrollTo(index)

    def update_row_color(self, row):
        """根据 is_new 的状态更新指定行的颜色"""
        is_new = False  # 这里可以通过某种方式获取新标志位的状态（例如重新从数据库读取）

        # 假设 is_new 是从某个地方获取的标志，判断当前行的颜色
        if is_new:
            color = Qt.GlobalColor.red
        else:
            color = Qt.GlobalColor.black

        # 更新整行的颜色
        for col in range(self.model.columnCount()):
            self.model.item(row, col).setForeground(color)

    def on_row_double_click(self, index):
        row = index.row()  # 获取被双击行的索引
        # 获取第五列的 URL
        url_item = self.model.item(row, 4)  # 第五列的索引是 4
        if url_item is not None:
            url = url_item.text()  # 获取 URL
            if url:
                webbrowser.open(url)  # 打开浏览器访问该 URL

    def load_image(self, image_path):
        if os.path.exists(image_path):
            pixmap = QPixmap(image_path)

            # 目标大小为 200x400
            target_size = QSize(300, 400)

            # 将图片缩放到适合目标大小，同时保持长宽比例
            scaled_pixmap = pixmap.scaled(target_size, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)

            # 创建一个空的 QPixmap，大小为目标大小
            new_pixmap = QPixmap(target_size)
            new_pixmap.fill(Qt.GlobalColor.transparent)  # 填充透明背景

            # 计算缩放后图片的位置，以使其居中
            x_offset = (target_size.width() - scaled_pixmap.width()) // 2
            y_offset = (target_size.height() - scaled_pixmap.height()) // 2

            # 将缩放后的图片绘制到新的 QPixmap 上
            painter = QPainter(new_pixmap)
            painter.drawPixmap(x_offset, y_offset, scaled_pixmap)
            painter.end()

            # 设置处理后的图片到 QLabel
            self.ui.imagelabel.setPixmap(new_pixmap)

    def display_data(self):
        logger.info("开始刷新数据列表。。。（display_data）")
        new_item = False

        # 记录当前滚动条位置
        current_scroll_pos = self.ui.tableView.verticalScrollBar().value()

        # 从数据库获取最新的数据并按 is_new 排序（新项目排在前面）
        new_data = sorted(get_data_from_db(), key=lambda x: x[7], reverse=True)

        if not new_data:
            logger.warning("没有从数据库获取到数据。")
            return

        # 清空表格，准备重新填充
        self.model.removeRows(0, self.model.rowCount())

        # 遍历新数据并填充表格
        for row_data in new_data:
            is_new = row_data[7]  # 假设 row_data[7] 是 is_new 标志
            new_row = [
                QStandardItem(row_data[2]),  # 标题
                QStandardItem(str(row_data[4])),  # 价格
                QStandardItem(row_data[3]),  # 提示
                QStandardItem(row_data[6]),  # 抓取时间
                QStandardItem(row_data[1]),  # 链接
                QStandardItem(row_data[5])  # 图片链接
            ]
            # 设置新数据为红色
            for item in new_row:
                item.setForeground(Qt.GlobalColor.red if is_new else Qt.GlobalColor.black)
            self.model.appendRow(new_row)

        # 恢复滚动条位置
        self.ui.tableView.verticalScrollBar().setValue(current_scroll_pos)

        if any(row_data[7] for row_data in new_data):
            winsound.PlaySound("new.wav", winsound.SND_FILENAME)

    def resizeEvent(self, event):
        # 窗口大小改变时调整表格列宽
        self.setup_table_view()
        super().resizeEvent(event)

    def closeEvent(self, event):
        """窗口关闭事件，保存关键字和过滤词"""
        self.save_cache()

        logger.info("关键字和过滤词已保存")
        event.accept()  # 接受关闭事件



if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec())
